home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d7 / lanuts.arc / CONFIG.C < prev    next >
Text File  |  1991-10-30  |  16KB  |  746 lines

  1. #pragma inline
  2.  
  3. /*********************************/
  4. /*                               */
  5. /*   CONFIG.C - by  Mike Klein   */
  6. /*                               */
  7. /*           ver 2.0             */
  8. /*                               */
  9. /*-------------------------------*/
  10. /*                               */
  11. /* A routine to show computer's  */
  12. /* configuration and optionally  */
  13. /* alter the parent environment  */
  14. /* SETting variables based upon  */
  15. /* the status of/equipment found */
  16. /* in the computer being used.   */
  17. /*                               */
  18. /*-------------------------------*/
  19. /*                               */
  20. /* FINISHED:  07/13/89           */
  21. /*                               */
  22. /*********************************/
  23.  
  24. /**************************************************/
  25. /*                                                */
  26. /* NOTE:  Users experiencing difficulty compiling */
  27. /* will probably want to remove the references to */
  28. /* in-line assembly code.  This is used only in   */
  29. /* the CPU determining function.  Also remove the */
  30. /* #pragma inline statement at the top of the     */
  31. /* listing.  Remember to compile with byte        */
  32. /* alignment.  The following are some function    */
  33. /* definitions that your compiler may not support */
  34. /* directly.  Use these defines to include them   */
  35. /* if that is the case.                           */
  36. /*                                                */
  37. /**************************************************/
  38.  
  39. /*
  40. #define MK_FP(seg,ofs)    ((void far *) \
  41.                (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  42. #define poke(a, b, c)   (*((int  far *) MK_FP((a), (b))) = (int) (c))
  43. #define pokeb(a, b, c)  (*((char far *) MK_FP((a), (b))) = (char) (c))
  44. #define peek(a, b)      (*((int  far *) MK_FP((a), (b))))
  45. #define peekb(a, b)     (*((char far *) MK_FP((a), (b))))
  46. */
  47.  
  48.  
  49. /*****************/
  50. /*               */
  51. /* INCLUDE FILES */
  52. /*               */
  53. /*****************/
  54.  
  55. #include <string.h>
  56. #include <dos.h>
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59.  
  60.  
  61. /***********/
  62. /*         */
  63. /* DEFINES */
  64. /*         */
  65. /***********/
  66.  
  67. #define VERSION 2.0
  68. #define TRUE 1
  69. #define FALSE 0
  70. #define VOID void
  71.  
  72. #define intvideo(regs) int86(0x10, regs, regs)
  73. #define intmouse(regs) int86(0x33, regs, regs)
  74.  
  75.  
  76. /*************/
  77. /*                 */
  78. /* TYPEDEF'S */
  79. /*                 */
  80. /*************/
  81.  
  82. typedef signed char BOOLEAN;
  83. typedef unsigned char BYTE;
  84. typedef signed char CHAR;
  85. typedef signed int INT;
  86. typedef unsigned int COUNTER;
  87.  
  88. typedef unsigned int SEGMENT;
  89. typedef unsigned int LENGTH;
  90.  
  91. CHAR far *par_env;        /* Pointer to parent environment    */
  92. LENGTH par_env_len;        /* Length of parent environment    */
  93.  
  94.  
  95. /****************/
  96. /*                     */
  97. /* DECLARATIONS */
  98. /*                     */
  99. /****************/
  100.  
  101. VOID put_par_env(CHAR *env_var, CHAR *env_text);
  102. VOID del_par_env(CHAR *env_var);
  103.  
  104.  
  105. /********/
  106. /*      */
  107. /* MAIN */
  108. /*      */
  109. /********/
  110.  
  111. VOID main(COUNTER argc, CHAR *argv[])
  112. {
  113.     CHAR *class;            /* Like model, but only (PC/AT)        */
  114.     CHAR conv[4];            /* Conventional memory size            */
  115.     CHAR *cpu;                /* CPU type (808x, 80286, 80386)        */
  116.     CHAR date[9];            /* System date                                */
  117.     CHAR *exp;                /* Expanded memory? (YES/NO)            */
  118.     CHAR *ext;                /*    Extended memory? (YES/NO)            */
  119.     CHAR *fpu;                /* FPU present? (YES/NO)                */
  120.     CHAR *mca;                /* Micro Channel? (YES/NO)                */
  121.     CHAR *mode;                /* Video mode (COLOR/MONOCHROME)        */
  122.     CHAR *model;            /* Model (PC/XT/XT-286/AT/25/30/50    */
  123.                                 /*          60/70/80)                        */
  124.     CHAR *mouse;            /* Mouse present? (YES/NO)                */
  125.     CHAR rom_date[9];        /* Computer's rom date                    */
  126.     CHAR *ps2;                /* PS/2 system? (YES/NO)                */
  127.     CHAR version[5];        /* DOS version (2.0, 3.3, etc.)        */
  128.     CHAR *video;            /* Video adapter (MDA, HERC, CGA,    */
  129.                                 /*                        EGA, PGA, VGA,        */
  130.                                 /*                        MCGA)                    */
  131.  
  132.     BYTE byte;
  133.     BYTE main;
  134.     BYTE sub;
  135.     BYTE features;
  136.  
  137.     CHAR far *far_ptr;
  138.     SEGMENT far *seg_ptr;
  139.     CHAR *emm_id;
  140.  
  141.     int env_set = FALSE;
  142.  
  143.     COUNTER i;
  144.  
  145.     union REGS regs;
  146.     struct SREGS sregs;
  147.  
  148.     struct date system_date;
  149.  
  150.     /* Structs for PSP and DOS Memory Control Block (MCB)        */
  151.  
  152.     typedef struct
  153.     {
  154.         CHAR misc1[22];
  155.         SEGMENT par_seg;
  156.         CHAR misc2[20];
  157.         SEGMENT env_seg;
  158.     } PSP;
  159.  
  160.     /* Compile with byte alignment */
  161.  
  162.     typedef struct
  163.     {
  164.         CHAR status;            /* Block is in chain or not         */
  165.         SEGMENT owner_psp;    /* PSP segment of block's owner    */
  166.         LENGTH size;            /* Size (in paragraphs) of block    */
  167.     } MCB;
  168.  
  169.     MCB far *config_mcb;        /* config.sys MCB        */
  170.     MCB far *command_mcb;    /* command.com MCB    */
  171.     MCB far *env_mcb;            /* environments MCB    */
  172.     PSP far *command_psp;    /* command.com PSP    */
  173.  
  174.  
  175.     /***************************/
  176.     /*                         */
  177.     /* COMMAND LINE PARAMETERS */
  178.     /*                         */
  179.     /***************************/
  180.  
  181.     if(argc > 1)
  182.         if(!strcmp(argv[1], "/e") || !strcmp(argv[1], "/E"))
  183.             env_set = TRUE;
  184.         else
  185.         {
  186.             puts("\nERROR:  Bad parameter...");
  187.             exit(-1);
  188.         }
  189.     else
  190.         env_set = FALSE;
  191.  
  192.  
  193.     /***************************/
  194.     /*                                    */
  195.     /* FIND PARENT ENVIRONMENT */
  196.     /*                                    */
  197.     /***************************/
  198.  
  199.     regs.x.ax = 0x5200;
  200.     intdosx(®s, ®s, &sregs);
  201.     seg_ptr = MK_FP(sregs.es, regs.x.bx - 2);
  202.  
  203.     config_mcb = MK_FP(*seg_ptr, 0);
  204.  
  205.     command_psp = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 2, 0);
  206.  
  207.     if(command_psp->env_seg == 0)
  208.     {
  209.         /* Environment is in block after parent program    */
  210.         command_mcb = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 1, 0);
  211.         par_env = MK_FP(FP_SEG(command_mcb) + command_mcb->size + 2, 0);
  212.     }
  213.     else                                            /* We have pointer to environment     */
  214.         par_env = MK_FP(command_psp->env_seg, 0);
  215.  
  216.     /* MCB of environment is 1 segment lower */
  217.  
  218.     env_mcb = MK_FP(FP_SEG(par_env) - 1, 0);
  219.  
  220.     par_env_len = env_mcb->size * 16;                /* Save len of environment    */
  221.  
  222.     printf("\n\nSYSTEM CONFIGURATION v%1.1f\n", VERSION);
  223.     puts("=========================");
  224.  
  225.  
  226.     /*************/
  227.     /*           */
  228.     /* MODEL/MCA */
  229.     /*           */
  230.     /*************/
  231.  
  232.     byte = peekb(0xf000, 0xfffe);        /* Get model byte    */
  233.     mca = "NO";
  234.     ps2 = "NO";
  235.  
  236.     switch(byte)
  237.     {
  238.         case 0xff :
  239.             model = "PC";
  240.             break;
  241.         case 0xfe :
  242.         case 0xfb :
  243.             model = "XT";
  244.             break;
  245.         case 0xfc :
  246.         case 0xfa :
  247.         case 0xf8 :
  248.             regs.x.ax = 0xc000;        /* Get the system environment info    */
  249.             int86x(0x15, ®s, ®s, &sregs);
  250.             main = peekb(sregs.es, regs.x.bx + 2);
  251.             if(byte != main)            /* Some AT's don't support this        */
  252.             {                                /* function so let's abort                */
  253.                 model = "AT";
  254.                 break;
  255.             }
  256.             sub = peekb(sregs.es, regs.x.bx + 3);
  257.             features = peekb(sregs.es, regs.x.bx + 5);
  258.             if(features & 0x02)
  259.                 mca = "YES";
  260.             switch(main)
  261.             {
  262.                 case 0xfc :
  263.                     switch(sub)
  264.                     {
  265.                         case 0x02 :
  266.                             model = "XT286";
  267.                             break;
  268.                         case 0x04 :
  269.                             model = "50";
  270.                             ps2 = "YES";
  271.                             break;
  272.                         case 0x05 :
  273.                             model = "60";
  274.                             ps2 = "YES";
  275.                             break;
  276.                         case 0x00 :
  277.                         case 0x01 :
  278.                         default :
  279.                             model = "AT";
  280.                             break;
  281.                     }
  282.                     break;
  283.                 case 0xf8 :
  284.                     ps2 = "YES";
  285.                     switch(sub)
  286.                     {
  287.                         case 0x00 :
  288.                         case 0x01 :
  289.                             model = "80";
  290.                             break;
  291.                         case 0x04 :
  292.                         case 0x09 :
  293.                         default :
  294.                             model = "70";
  295.                             break;
  296.                     }
  297.                     break;
  298.                 case 0xfa :
  299.                     ps2 = "YES";
  300.                     switch(sub)
  301.                     {
  302.                         case 0x01 :
  303.                             model = "25";
  304.                             break;
  305.                         case 0x00 :
  306.                         default :
  307.                             model = "30";
  308.                             break;
  309.                     }
  310.                     break;
  311.                 default :
  312.                     model = "N/A";
  313.                     break;
  314.             }
  315.             break;
  316.         default :
  317.             model = "N/A";
  318.             break;
  319.     }
  320.     printf("MODEL.....%s\n", model);
  321.     printf("PS/2......%s\n", ps2);
  322.     printf("MCA.......%s\n", mca);
  323.     if(env_set)
  324.     {
  325.         put_par_env("MODEL", model);
  326.         put_par_env("PS/2", ps2);
  327.         put_par_env("MCA", mca);
  328.     }
  329.  
  330.  
  331.     /************/
  332.     /*          */
  333.     /* CPU TYPE */
  334.     /*          */
  335.     /************/
  336.  
  337.     asm    pushf
  338.     asm    xor    ax,ax
  339.     asm    push    ax
  340.     asm    popf
  341.     asm    pushf
  342.     asm    pop    ax
  343.     asm    and    ax,0f000h
  344.     asm    cmp    ax,0f000h
  345.     asm    jz        is_808x
  346.  
  347.     asm    mov    ax,07000h    /* If we can't set bits 12-14 then    */
  348.     asm    push    ax                /* CPU is 80286                            */
  349.     asm    popf
  350.     asm    pushf
  351.     asm    pop    ax
  352.     asm    and    ax,07000h
  353.     asm    jz        is_80286
  354.  
  355.     is_80386 :
  356.     asm    mov    ax,386h
  357.     asm    jmp    done
  358.  
  359.     is_80286 :
  360.     asm    mov    ax,286h
  361.     asm    jmp    done
  362.  
  363.     is_808x :
  364.     asm    mov    ax,86h
  365.  
  366.     done:
  367.     asm    popf
  368.  
  369.     switch(_AX)
  370.     {
  371.         case 0x386 :
  372.             cpu = "80386";
  373.             class = "AT";
  374.             break;
  375.         case 0x286 :
  376.             cpu = "80286";
  377.             class = "AT";
  378.             break;
  379.         case 0x86 :
  380.             cpu = "808x";
  381.             class = "PC";
  382.             break;
  383.         default :
  384.             cpu = "N/A";
  385.             break;
  386.     }
  387.     printf("CPU.......%s\n", cpu);
  388.     printf("CLASS.....%s\n", class);
  389.     if(env_set)
  390.     {
  391.         put_par_env("CPU", cpu);
  392.         put_par_env("CLASS", class);
  393.     }
  394.  
  395.  
  396.    /**************/
  397.    /*            */
  398.    /* MATH CHIP? */
  399.    /*            */
  400.    /**************/
  401.  
  402.     int86(0x11, ®s, ®s);                    /* Get BIOS equip word for FPU    */
  403.     fpu = (regs.x.ax & 0x02) ? "YES" : "NO";
  404.  
  405.     printf("FPU.......%s\n", fpu);
  406.     if(env_set)
  407.         put_par_env("FPU", fpu);
  408.  
  409.  
  410.     /************/
  411.     /*          */
  412.     /* GET DATE */
  413.     /*          */
  414.     /************/
  415.  
  416.     regs.x.ax = 0x0400;
  417.     int86(0x1a, ®s, ®s);
  418.     sprintf(date, "%02x/%02x/%02x", regs.h.dh, regs.h.dl, regs.h.cl);
  419.  
  420.     printf("DATE......%s\n", date);
  421.     if(env_set)
  422.         put_par_env("DATE", date);
  423.  
  424.  
  425.     /***********************/
  426.     /*                     */
  427.     /* CONVENTIONAL MEMORY */
  428.     /*                     */
  429.     /***********************/
  430.  
  431.     int86(0x12, ®s, ®s);                    /* INT 0x12 returns conv memory    */
  432.     if((regs.x.ax % 2) != 0)                    /* Some systems report 1K less    */
  433.         ++regs.x.ax;                                /* than actual, so we compensate */
  434.     sprintf(conv, "%u", regs.x.ax);
  435.  
  436.     printf("CONV......%s\n", conv);
  437.     if(env_set)
  438.         put_par_env("CONV", conv);
  439.  
  440.  
  441.     /*******************/
  442.     /*                 */
  443.     /* EXPANDED MEMORY */
  444.     /*                 */
  445.     /*******************/
  446.  
  447.     emm_id = "EMMXXXX0";
  448.  
  449.     regs.x.ax = 0x3567;
  450.     intdosx(®s, ®s, &sregs);
  451.     far_ptr = MK_FP(sregs.es, 10);
  452.  
  453.     for(i=0; i < 8; i++)
  454.     {
  455.         if(far_ptr[i] != emm_id[i])
  456.         {
  457.             exp = "NO";
  458.             break;
  459.         }
  460.     }
  461.     if(i == 8)
  462.     {
  463.         exp = "YES";
  464.         regs.h.ah = 0x42;
  465.         int86(0x67, ®s, ®s);
  466.     }
  467.  
  468.     printf("EXP.......%s", exp);
  469.     if(i == 8)
  470.         printf(" (%dK)\n", regs.x.bx * 16);
  471.     else
  472.         printf("\n");
  473.     if(env_set)
  474.         put_par_env("EXP", exp);
  475.  
  476.  
  477.     /*******************/
  478.     /*                 */
  479.     /* EXTENDED MEMORY */
  480.     /*                 */
  481.     /*******************/
  482.  
  483.     /* This code must follow the CPU code    */
  484.  
  485.     if(! strcmp(class, "AT"))
  486.     {
  487.         regs.x.ax = 0x8800;
  488.         int86(0x15, ®s, ®s);
  489.         i = regs.x.ax;
  490.         if((i != 0x8800) && (i != 0x0000))
  491.             ext = "YES";
  492.         else
  493.             ext = "NO";
  494.     }
  495.     else
  496.         ext = "NO";
  497.  
  498.     printf("EXT.......%s", ext);
  499.     if(!strcmp(ext, "YES"))
  500.         printf(" (%dK)\n", i);
  501.     else
  502.         printf("\n");
  503.     if(env_set)
  504.         put_par_env("EXT", ext);
  505.  
  506.  
  507.     /**********/
  508.    /*        */
  509.    /* MOUSE? */
  510.    /*        */
  511.    /**********/
  512.  
  513.     regs.x.ax = 0x00;            /* Mouse Func 0 - initialize    */
  514.     intmouse(®s);
  515.     if(regs.x.ax)
  516.         mouse = "YES";
  517.     else
  518.         mouse = "NO";
  519.  
  520.     printf("MOUSE.....%s\n", mouse);
  521.     if(env_set)
  522.         put_par_env("MOUSE", mouse);
  523.  
  524.  
  525.     /************/
  526.     /*          */
  527.     /* ROM DATE */
  528.     /*          */
  529.     /************/
  530.  
  531.     far_ptr = MK_FP(0xf000, 0xfff5);        /* Make pointer to address        */
  532.                                                     /* of computer's rom date        */
  533.     if(far_ptr[2] == far_ptr[5])
  534.     {
  535.         for(i=0; i<8; ++i)
  536.             rom_date[i] = far_ptr[i];        /* Make string from far_ptr    */
  537.         rom_date[i] = '\0';
  538.     }
  539.     else
  540.         strcpy(rom_date, "N/A");
  541.  
  542.     printf("ROM DATE..%s\n", rom_date);
  543.     if(env_set)
  544.         put_par_env("ROM_DATE", rom_date);
  545.  
  546.  
  547.     /**************/
  548.     /*            */
  549.     /* VIDEO MODE */
  550.     /*            */
  551.     /**************/
  552.  
  553.     regs.x.ax = 0x0f00;
  554.     intvideo(®s);
  555.     switch(regs.h.al)
  556.     {
  557.         case 0x00 :
  558.         case 0x02 :
  559.         case 0x07 :
  560.             mode = "MONOCHROME";
  561.             break;
  562.         default :
  563.             mode = "COLOR";
  564.             break;
  565.     }
  566.  
  567.     printf("MODE......%s\n", mode);
  568.     if(env_set)
  569.         put_par_env("MODE", mode);
  570.  
  571.  
  572.    /*****************/
  573.    /*               */
  574.    /* VIDEO ADAPTER */
  575.    /*               */
  576.    /*****************/
  577.  
  578.     regs.x.ax = 0x1a00;            /* If function supported (_AL=0x1A)    */
  579.     intvideo(®s);
  580.     if(regs.h.al == 0x1a)
  581.     {
  582.         switch(regs.h.bl)
  583.         {
  584.             case 0x01 :
  585.                 video = "MDA";
  586.                 break;
  587.             case 0x02 :
  588.                 video = "CGA";
  589.                 break;
  590.             case 0x04 :
  591.             case 0x05 :
  592.                 video = "EGA";
  593.                 break;
  594.             case 0x06 :
  595.                 video = "PGA";
  596.                 break;
  597.             case 0x07 :
  598.             case 0x08 :
  599.                 video = "VGA";
  600.                 break;
  601.             case 0x0a :
  602.             case 0x0b :
  603.             case 0x0c :
  604.                 video = "MCGA";
  605.                 break;
  606.             default :
  607.                 video = "VGA";
  608.                 break;
  609.         }
  610.     }
  611.     else
  612.     {
  613.         regs.h.ah = 0x12;                        /* Get config info for EGA/VGA        */
  614.         regs.h.bl = 0x10;
  615.         intvideo(®s);
  616.         if(regs.h.bl != 0x10)
  617.             video = "EGA";                        /* BL changed? Then EGA                    */
  618.         else
  619.         {
  620.             regs.h.ah = 0x0f;                    /* See if color or mono                    */
  621.             intvideo(®s);
  622.             if(regs.h.al == 7)
  623.             {                                        /* Read CRT status port, mask bit 7 */
  624.                 byte = inport(0x3ba) & 0x80;
  625.                 for(i = 0; i < 32767; i++)    /* Will bit 7 change?                    */
  626.                     if(byte != inport(0x3ba) & 0x80)
  627.                         break;                    /* If bit 7 didn't change, then MDA    */
  628.                 video = (i != 32767) ? "HERC" : "MDA";
  629.             }
  630.             else
  631.                 video = "CGA";
  632.         }
  633.     }
  634.     printf("VIDEO.....%s\n", video);
  635.     if(env_set)
  636.         put_par_env("VIDEO", video);
  637.  
  638.  
  639.     /***************/
  640.    /*             */
  641.    /* DOS VERSION */
  642.    /*             */
  643.    /***************/
  644.  
  645.     regs.h.ah = 0x30;                            /* INT 0x21 FUNC 0x30 to get DOS    */
  646.     intdos(®s, ®s);                    /* version number                        */
  647.  
  648.     sprintf(version, "%u.%u", (unsigned) regs.h.al, (unsigned) regs.h.ah);
  649.     printf("VERSION...%s\n", version);
  650.     if(env_set)
  651.         put_par_env("VERSION", version);
  652.  
  653.     puts("=========================\n");
  654.  
  655. }
  656.  
  657.  
  658. /***************/
  659. /*                    */
  660. /* PUT_PAR_ENV */
  661. /*                    */
  662. /***************/
  663.  
  664. VOID put_par_env(CHAR *env_var, CHAR *env_text)
  665. {
  666.  
  667.     CHAR far *far0;
  668.     LENGTH len;
  669.     CHAR env_str[256];
  670.     CHAR *str;
  671.  
  672.     strcpy(env_str, env_var);                /* Create environment string        */
  673.     strcat(env_str, "=");
  674.     strcat(env_str, env_text);
  675.     strupr(env_str);
  676.  
  677.     del_par_env(env_var);                    /* Delete variable of same name    */
  678.  
  679.     /* Find end of environment by looking for 2 NULLS */
  680.     for(far0 = par_env, len = 0; !(!*far0 && !*(far0+1)); ++far0, ++len)
  681.         ;
  682.  
  683.     len = par_env_len - (len + 2);        /* Get free space in environment    */
  684.  
  685.     if(len < strlen(env_str) + 1)
  686.     {                                                /* If out of room, return error    */
  687.         puts("\nERROR:  Out of environment space...\n");
  688.         exit(-1);
  689.     }
  690.  
  691.     str = env_str;
  692.  
  693.     for(++far0; *str; *far0++ = *str++)    /* Copy str to end of par env        */
  694.         ;
  695.  
  696.     *far0 = 0;    /* End env with 2 nulls */
  697.     ++far0;
  698.     *far0 = 0;
  699.  
  700. }
  701.  
  702.  
  703. /***************/
  704. /*                    */
  705. /* DEL_PAR_ENV */
  706. /*                    */
  707. /***************/
  708.  
  709. VOID del_par_env(CHAR *env_var)
  710. {
  711.  
  712.     CHAR far *far1;        /* Beginning of next variable    */
  713.     CHAR far *far2;        /* Beginning of the variable    */
  714.     CHAR *str;                /* env_var ptr used in search    */
  715.  
  716.     int found = FALSE;    /* End of search flag            */
  717.  
  718.     far1 = par_env;
  719.  
  720.     while(*far1 && !found)
  721.     {                                                /* Find start of variable to delete    */
  722.         str = env_var;
  723.         far2 = far1;
  724.         for(;(*far1 == *str) && (*far1 != '=') && *far1 && *str; ++far1, ++str)
  725.             ;
  726.         if((!*str) && (*far1 == '='))
  727.             found = TRUE;            /* We found it!            */
  728.         for(; *far1; ++far1)
  729.             ;
  730.         ++far1;
  731.     }
  732.  
  733.     if(!*far1 && !found)            /* Find env_var?            */
  734.         return;                        /* No, we didn't            */
  735.  
  736.     /* Shift environment down, to cover env_var            */
  737.  
  738.     for(; !(!*far1 && !*(far1+1)); *far2++ = *far1++)
  739.         ;
  740.  
  741.     *far2 = 0;    /* End env with 2 nulls */
  742.     ++far2;
  743.     *far2 = 0;
  744.  
  745. }
  746.